//! RK3588 Timer Register Definitions
//!
//! Based on RK3588 TRM Chapter 10 - Timer

/// Timer control modes
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TimerMode {
    /// Free-running mode - automatically reloads and continues
    FreeRunning = 0,
    /// User-defined count mode - stops after reaching target
    UserDefined = 1,
}

/// Timer type (increment or decrement)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TimerType {
    /// Count up timer (NICTIMER)
    Increment,
    /// Count down timer (NDCTIMER)
    Decrement,
}

/// Register offsets for Normal Count TIMER
/// For 2-channel TIMER, channel 1 base = channel 0 base + 0x20
pub mod offset {
    /// Timer Load Count Register 0 (Lower 32 bits)
    pub const LOAD_COUNT0: usize = 0x0000;

    /// Timer Load Count Register 1 (Higher 32 bits)
    pub const LOAD_COUNT1: usize = 0x0004;

    /// Timer Current Value Register 0 (Lower 32 bits) - Read Only
    pub const CURRENT_VALUE0: usize = 0x0008;

    /// Timer Current Value Register 1 (Higher 32 bits) - Read Only
    pub const CURRENT_VALUE1: usize = 0x000C;

    /// Timer Control Register
    pub const CONTROL_REG: usize = 0x0010;

    /// Timer Interrupt Status Register
    pub const INT_STATUS: usize = 0x0018;

    /// Timer Revision Register (at base + 0xF0 for the entire timer module)
    pub const REVISION: usize = 0x00F0;

    /// Offset between channels in multi-channel timer
    pub const CHANNEL_OFFSET: usize = 0x0020;
}

/// Control register bit definitions
pub mod control {
    /// Timer enable bit (bit 0)
    pub const TIMER_ENABLE: u32 = 1 << 0;

    /// Timer mode bit (bit 1)
    /// 0 = Free-running mode
    /// 1 = User-defined count mode
    pub const TIMER_MODE_SHIFT: u32 = 1;
    pub const TIMER_MODE_MASK: u32 = 1 << TIMER_MODE_SHIFT;

    /// Timer interrupt enable bit (bit 2)
    pub const TIMER_INT_ENABLE: u32 = 1 << 2;
}

/// 2-Channel Timer Revision Register bit fields
pub mod revision_2ch {
    /// SVN revision field [31:16]
    pub const SVN_REVISION_SHIFT: u32 = 16;
    pub const SVN_REVISION_MASK: u32 = 0xFFFF << SVN_REVISION_SHIFT;

    /// Channel 1 type [9]
    /// 0 = Count down counter
    /// 1 = Count up counter
    pub const CH1_TYPE_SHIFT: u32 = 9;
    pub const CH1_TYPE_MASK: u32 = 1 << CH1_TYPE_SHIFT;

    /// Channel 0 type [8]
    /// 0 = Count down counter
    /// 1 = Count up counter
    pub const CH0_TYPE_SHIFT: u32 = 8;
    pub const CH0_TYPE_MASK: u32 = 1 << CH0_TYPE_SHIFT;

    /// IP function field [7:0]
    pub const IP_FUNCTION_MASK: u32 = 0xFF;

    /// Expected value for 2-channel timer
    pub const EXPECTED_VALUE: u32 = 0x15650302;
}

/// Timer base addresses for RK3588 (from TRM Table 10-1)
pub mod base_addr {
    /// TIMER_PMU: 2-channel, PD: pd_pmu1
    pub const TIMER_PMU: usize = 0xFD8F0000;

    /// TIMER_NPU: 2-channel, PD: pd_npu
    pub const TIMER_NPU: usize = 0xFDB00000;

    /// TIMER_DDR: 2-channel, PD: pd_center
    pub const TIMER_DDR: usize = 0xFE118000;
}

/// Helper functions for register manipulation
impl TimerMode {
    /// Convert to control register value
    pub fn to_bits(self) -> u32 {
        (self as u32) << control::TIMER_MODE_SHIFT
    }
}
